home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Files / Un⁄mount / Un⁄mount.c < prev    next >
Encoding:
Text File  |  1997-03-07  |  6.7 KB  |  333 lines  |  [TEXT/CWIE]

  1. #define OLDROUTINELOCATIONS        0
  2. #define OLDROUTINENAMES            0
  3. #define SystemSevenOrLater        1
  4.  
  5. #ifndef __DISKS__
  6. #    include <Disks.h>
  7. #endif
  8.  
  9. #ifndef __DEVICES__
  10. #    include <Devices.h>
  11. #endif
  12.  
  13. #ifndef __FILES__
  14. #    include <Files.h>
  15. #endif
  16.  
  17. #ifndef __DISKINIT__
  18. #    include <DiskInit.h>
  19. #endif
  20.  
  21. #ifndef __FONTS__
  22. #    include <Fonts.h>
  23. #endif
  24.  
  25. #ifndef __DIALOGS__
  26. #    include <Dialogs.h>
  27. #endif
  28.  
  29. enum
  30. {
  31.     kResID_Dialog_MountUnmount = 128,
  32.     kResID_Dialog_Main
  33. };
  34.  
  35. enum
  36. {
  37.     kDialogItem_MountUnmount_None,
  38.     kDialogItem_MountUnmount_Button_Done,
  39.     kDialogItem_MountUnmount_StaticText_Waiting,
  40.     kDialogItem_MountUnmount_StaticText_VolName,
  41.     kDialogItem_MountUnmount_Button_Eject,
  42.     kDialogItem_MountUnmount_StaticText_HaveDisk
  43. };
  44.  
  45. static pascal OSErr InitMac (void)
  46. {
  47.     MaxApplZone ( );
  48.     InitGraf (&(qd.thePort));
  49.     InitFonts ( );
  50.     InitWindows ( );
  51.     InitMenus ( );
  52.     TEInit ( );
  53.     InitDialogs (nil);
  54.  
  55.     return noErr;
  56. }
  57.  
  58. static pascal void SetWatchCursor (void)
  59. {
  60.     SetCursor (*GetCursor (watchCursor));
  61. }
  62.  
  63. static pascal void ReconfigureInterfaceAfterMount (DialogRef dialog, Str27 volName)
  64. {
  65.     short    iType;
  66.     Handle    iHandle;
  67.     Rect    iRect;
  68.  
  69.     GetDialogItem (dialog,kDialogItem_MountUnmount_StaticText_VolName,
  70.         &iType, &iHandle, &iRect);
  71.     SetDialogItemText (iHandle,volName);
  72.  
  73.     GetDialogItem (dialog,kDialogItem_MountUnmount_Button_Eject,
  74.         &iType, &iHandle, &iRect);
  75.     HiliteControl ((ControlHandle) iHandle, 0);
  76.  
  77.     HideDialogItem (dialog,kDialogItem_MountUnmount_StaticText_Waiting);
  78.     ShowDialogItem (dialog,kDialogItem_MountUnmount_StaticText_HaveDisk);
  79. }
  80.  
  81. static pascal Boolean DriveIsFloppy (short driveNum)
  82. {
  83.     // this function isn't perfect but it isn't the purpose of this sample;
  84.     // a real program would qualify volumes much better
  85.  
  86.     return driveNum == 1 || driveNum == 2;
  87. }
  88.  
  89. static pascal OSErr AfterMount (OSErr mountErr, short driveNum, DialogRef dialog)
  90. {
  91.     OSErr err = noErr;
  92.  
  93.     // if mount failed, try to format and retry mount
  94.  
  95.     if (mountErr)
  96.     {
  97.         Point dibmWhere = { -1,-1 };
  98.         long fakeEventMessage = (((UInt32) mountErr) << 16) | driveNum;
  99.         err = DIBadMount (dibmWhere, fakeEventMessage);
  100.     }
  101.  
  102.     // regardless of whether we had to reformat the disk,
  103.     // if we successfully mounted it...
  104.  
  105.     if (!err && DriveIsFloppy (driveNum))
  106.     {
  107.         OSErr err2;
  108.  
  109.         // get the volume's name and poke it into the dialog
  110.  
  111.         Str27    volName;
  112.         short    vRefNum;
  113.         long    freeBytes;
  114.  
  115.         err = GetVInfo (driveNum, volName, &vRefNum, &freeBytes);
  116.  
  117.         if (err)
  118.         {
  119.             SysBeep (10);
  120.             SetWRefCon (dialog, 0);
  121.         }
  122.         else
  123.         {
  124.             ReconfigureInterfaceAfterMount (dialog,volName);
  125.             SetWRefCon (dialog, driveNum);
  126.         }
  127.  
  128.         // get rid of the newly-mounted volume (but don't eject its disk)
  129.  
  130.         err2 = UnmountVol (nil, driveNum);
  131.         if (!err2) err = err2;
  132.     }
  133.  
  134.     return err;
  135. }
  136.  
  137. static pascal Boolean GetNextEventModalFilterProc
  138.     (DialogRef dialog, EventRecord *event, short *itemHit)
  139. {
  140.     Boolean result = StdFilterProc (dialog,event,itemHit);
  141.  
  142.     if (event->what == nullEvent)
  143.     {
  144.         EventRecord diskInsertedEvent;
  145.  
  146.         // is there an unrequited disk-inserted event in the queue?
  147.  
  148.         if (OSEventAvail (diskMask, &diskInsertedEvent))
  149.         {
  150.             // it takes a while to mount a disk
  151.  
  152.             SetWatchCursor ( );
  153.  
  154.             // let the system mount the disk
  155.  
  156.             if (GetNextEvent (diskMask, &diskInsertedEvent))
  157.             {
  158.                 OSErr    err            = diskInsertedEvent.message >> 16;
  159.                 short    driveNum    = diskInsertedEvent.message;
  160.  
  161.                 err = AfterMount (err,driveNum,dialog);
  162.                 if (err) SysBeep (10);
  163.             }
  164.         }
  165.     }
  166.  
  167.     return result;
  168. }
  169.  
  170. static pascal Boolean GetOSEventModalFilterProc
  171.     (DialogRef dialog, EventRecord *event, short *itemHit)
  172. {
  173.     Boolean result = StdFilterProc (dialog,event,itemHit);
  174.  
  175.     if (event->what == nullEvent)
  176.     {
  177.         EventRecord diskInsertedEvent;
  178.  
  179.         // pull disk-inserted events from the queue before
  180.         // system mounts associated volume
  181.  
  182.         if (GetOSEvent (diskMask, &diskInsertedEvent))
  183.         {
  184.             ParamBlockRec    pbr;
  185.             short            driveNum = diskInsertedEvent.message;
  186.  
  187.             // mounting takes a while
  188.  
  189.             SetWatchCursor ( );
  190.  
  191.             // [attempt to mount the volume ourselves] and [react accordingly]
  192.  
  193.             pbr.volumeParam.ioVRefNum = driveNum;
  194.             if (AfterMount (PBMountVol (&pbr), driveNum, dialog))
  195.                 SysBeep (10);
  196.         }
  197.     }
  198.  
  199.     return result;
  200. }
  201.  
  202. static pascal void DisableEjectButton (DialogRef dlgRef)
  203. {
  204.     short    iType;
  205.     Handle    iHandle;
  206.     Rect    iRect;
  207.  
  208.     GetDialogItem (dlgRef,kDialogItem_MountUnmount_Button_Eject,
  209.         &iType,&iHandle,&iRect);
  210.     HiliteControl ((ControlHandle) iHandle, 255);
  211. }
  212.  
  213. static pascal void ReconfigureInterfaceAfterEject (DialogRef dlgRef)
  214. {
  215.     short    iType;
  216.     Handle    iHandle;
  217.     Rect    iRect;
  218.  
  219.     GetDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_VolName,
  220.         &iType, &iHandle, &iRect);
  221.     SetDialogItemText (iHandle,"\p");
  222.     ShowDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_Waiting);
  223.     HideDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_HaveDisk);
  224.     DisableEjectButton (dlgRef);
  225. }
  226.  
  227. static pascal OSErr EjectIfAny (DialogRef dlgRef)
  228. {
  229.     OSErr err = noErr;
  230.  
  231.     short driveNum = GetWRefCon (dlgRef);
  232.  
  233.     if (driveNum)
  234.     {
  235.         SetWatchCursor ( );
  236.  
  237.         if (!(err = Eject (nil, driveNum)))
  238.             SetWRefCon (dlgRef,0);
  239.     }
  240.  
  241.     return err;
  242. }
  243.  
  244.  
  245. static pascal void MountUnmount (ModalFilterProcPtr mfpp)
  246. {
  247.     ModalFilterUPP modalFilterUPP = NewModalFilterProc (mfpp);
  248.     if (modalFilterUPP)
  249.     {
  250.         DialogRef dlgRef = GetNewDialog (kResID_Dialog_MountUnmount,nil,(WindowRef)-1);
  251.         if (dlgRef)
  252.         {
  253.             short itemHit;
  254.  
  255.             SetDialogDefaultItem (dlgRef,ok);
  256.             SetDialogTracksCursor (dlgRef,true);
  257.             DisableEjectButton (dlgRef);
  258.             ShowWindow (dlgRef);
  259.  
  260.             do
  261.             {
  262.                 ModalDialog (modalFilterUPP,&itemHit);
  263.  
  264.                 if (itemHit == kDialogItem_MountUnmount_Button_Eject)
  265.                 {
  266.                     if (EjectIfAny (dlgRef))
  267.                         { SysBeep (10); break; }
  268.                     else
  269.                         ReconfigureInterfaceAfterEject (dlgRef);
  270.                 }
  271.             }
  272.             while (kDialogItem_MountUnmount_Button_Done != itemHit);
  273.  
  274.             if (EjectIfAny (dlgRef)) SysBeep (10);
  275.             DisposeDialog (dlgRef);
  276.         }
  277.  
  278.         DisposeRoutineDescriptor (modalFilterUPP);
  279.     }
  280. }
  281.  
  282. void main (void)
  283. {
  284.     if (InitMac ( ))
  285.         SysBeep (10);
  286.     else
  287.     {
  288.         DialogRef dlgRef = GetNewDialog (kResID_Dialog_Main,nil,(WindowRef)-1);
  289.         if (dlgRef)
  290.         {
  291.             ModalFilterUPP modalFilterUPP;
  292.  
  293.             if (GetStdFilterProc (&modalFilterUPP))
  294.                 SysBeep (10);
  295.             else
  296.             {
  297.                 enum
  298.                 {
  299.                     kDialogItem_None,
  300.                     kDialogItem_Button_Quit,
  301.                     kDialogItem_Button_GetNextEvent,
  302.                     kDialogItem_Button_GetOSEvent
  303.                 };
  304.  
  305.                 short itemHit;
  306.  
  307.                 SetDialogDefaultItem (dlgRef,kDialogItem_Button_Quit);
  308.                 SetDialogTracksCursor (dlgRef,true);
  309.  
  310.                 do
  311.                 {
  312.                     ModalDialog (modalFilterUPP,&itemHit);
  313.  
  314.                     switch (itemHit)
  315.                     {
  316.                         case kDialogItem_Button_GetNextEvent    :
  317.  
  318.                             MountUnmount (GetNextEventModalFilterProc);
  319.                             break;
  320.  
  321.                         case kDialogItem_Button_GetOSEvent        :
  322.  
  323.                             MountUnmount (GetOSEventModalFilterProc);
  324.                             break;
  325.                     }
  326.                 }
  327.                 while (itemHit != kDialogItem_Button_Quit);
  328.             }
  329.             DisposeDialog (dlgRef);
  330.         }
  331.     }
  332. }
  333.